<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>极简验证码测试</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
            text-align: center;
        }
        h1 {
            color: #333;
        }
        .captcha-container {
            margin: 20px 0;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        img {
            border: 1px solid #ddd;
            margin: 10px 0;
        }
        button {
            padding: 10px 20px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-top: 10px;
        }
        button:hover {
            background-color: #45a049;
        }
        .log-container {
            margin-top: 20px;
            text-align: left;
            font-family: monospace;
            white-space: pre-wrap;
            background-color: #f5f5f5;
            padding: 10px;
            border-radius: 4px;
            max-height: 300px;
            overflow-y: auto;
        }
        .error {
            color: red;
        }
        .success {
            color: green;
        }
        .info {
            color: blue;
        }
        .warn {
            color: orange;
        }
    </style>
</head>
<body>
    <h1>极简验证码测试</h1>
    <p>这个页面直接在加载时尝试获取验证码，并提供详细的调试信息</p>
    
    <div class="captcha-container">
        <h2>验证码</h2>
        <img id="captchaImage" alt="验证码" style="max-width: 100%;" />
        <button id="refreshBtn">刷新验证码</button>
    </div>
    
    <div class="log-container" id="logContainer"></div>
    
    <script>
        const captchaImage = document.getElementById('captchaImage');
        const refreshBtn = document.getElementById('refreshBtn');
        const logContainer = document.getElementById('logContainer');
        
        // 日志记录函数
        function log(message, type = 'info') {
            const timestamp = new Date().toLocaleTimeString();
            const logEntry = document.createElement('div');
            logEntry.className = type;
            logEntry.textContent = `[${timestamp}] ${message}`;
            logContainer.appendChild(logEntry);
            logContainer.scrollTop = logContainer.scrollHeight;
            
            // 同时输出到控制台
            if (type === 'error') {
                console.error('%c' + message, 'color: red');
            } else if (type === 'success') {
                console.log('%c' + message, 'color: green');
            } else if (type === 'warn') {
                console.warn('%c' + message, 'color: orange');
            } else {
                console.log('%c' + message, 'color: blue');
            }
        }
        
        // 测试验证码API
        function testCaptchaApi() {
            // 清空之前的结果
            captchaImage.src = '';
            captchaImage.alt = '加载中...';
            
            log('开始测试验证码API...', 'info');
            log(`当前页面URL: ${window.location.href}`, 'info');
            log(`浏览器: ${navigator.userAgent}`, 'info');
            log(`document.domain: ${document.domain}`, 'info');
            log(`window.origin: ${window.origin}`, 'info');
            
            try {
                const timestamp = new Date().getTime();
                // 直接使用后端服务的完整URL
                const url = `http://localhost:8000/api/auth/captcha?t=${timestamp}`;
                
                log(`准备发送请求到: ${url}`, 'info');
                
                // 记录请求开始时间
                const startTime = performance.now();
                
                // 使用XMLHttpRequest代替fetch，以获得更详细的错误信息
                const xhr = new XMLHttpRequest();
                xhr.open('GET', url, true);
                xhr.withCredentials = true; // 包含cookies以支持跨域请求
                xhr.setRequestHeader('Accept', 'application/json');
                xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
                xhr.setRequestHeader('Pragma', 'no-cache');
                xhr.setRequestHeader('Expires', '0');
                
                // 设置响应类型
                xhr.responseType = 'json';
                
                // 监听进度事件
                xhr.addEventListener('progress', (event) => {
                    if (event.lengthComputable) {
                        const percentComplete = (event.loaded / event.total) * 100;
                        log(`请求进度: ${percentComplete.toFixed(2)}%`, 'info');
                    }
                });
                
                // 监听状态变化
                xhr.addEventListener('readystatechange', () => {
                    log(`XMLHttpRequest状态变化: readyState=${xhr.readyState}`, 'info');
                    
                    if (xhr.readyState === 4) {
                        const endTime = performance.now();
                        log(`请求完成，耗时: ${Math.round(endTime - startTime)}ms`, 'info');
                        log(`响应状态码: ${xhr.status} ${xhr.statusText}`, xhr.status === 200 ? 'success' : 'error');
                        
                        // 打印响应头信息
                        log('响应头信息:', 'info');
                        const headers = xhr.getAllResponseHeaders().split('\n');
                        headers.forEach(header => {
                            if (header.trim()) {
                                log(`  ${header}`, 'info');
                            }
                        });
                        
                        // 检查CORS相关头
                        const accessControlAllowOrigin = xhr.getResponseHeader('access-control-allow-origin');
                        if (accessControlAllowOrigin) {
                            log(`CORS允许的源: ${accessControlAllowOrigin}`, 'success');
                        } else {
                            log('警告: 未检测到CORS允许源头', 'warn');
                        }
                        
                        if (xhr.status === 200) {
                            try {
                                const data = xhr.response;
                                log('成功获取验证码数据!', 'success');
                                log('返回数据: ' + JSON.stringify(data, null, 2), 'success');
                                
                                if (data && data.captchaImage) {
                                    captchaImage.src = data.captchaImage;
                                    captchaImage.alt = '验证码';
                                    log('验证码图片显示成功!', 'success');
                                } else {
                                    log('错误: 验证码数据格式不正确', 'error');
                                    captchaImage.alt = '验证码数据格式不正确';
                                }
                            } catch (jsonError) {
                                log(`解析JSON响应失败: ${jsonError.message}`, 'error');
                                log(`响应文本: ${xhr.responseText.substring(0, 100)}...`, 'error');
                                captchaImage.alt = '解析JSON失败';
                            }
                        } else {
                            log(`获取验证码失败: HTTP ${xhr.status} ${xhr.statusText}`, 'error');
                            log(`响应文本: ${xhr.responseText || '空响应'}`, 'error');
                            captchaImage.alt = `获取失败: ${xhr.status}`;
                        }
                    }
                });
                
                // 监听错误事件
                xhr.addEventListener('error', (error) => {
                    const endTime = performance.now();
                    log(`请求错误，耗时: ${Math.round(endTime - startTime)}ms`, 'error');
                    log(`网络错误: ${error.type}`, 'error');
                    log(`错误详情: ${JSON.stringify(error, Object.getOwnPropertyNames(error))}`, 'error');
                    captchaImage.alt = '网络错误';
                    
                    // 常见错误原因分析
                    log('\n可能的原因:', 'error');
                    log('1. 后端服务未运行 - 请确认Spring Boot服务是否启动', 'error');
                    log('2. 防火墙阻止了连接 - 检查本地防火墙设置', 'error');
                    log('3. CORS配置不正确 - 检查后端CORS配置', 'error');
                    log('4. 浏览器安全策略限制 - 尝试在不同浏览器测试', 'error');
                    log('5. 网络连接问题 - 检查本地网络连接', 'error');
                    log('6. 端口号错误 - 确认后端服务端口是否为8000', 'error');
                    log('7. API路径错误 - 确认后端API路径是否为/api/auth/captcha', 'error');
                });
                
                // 监听超时事件
                xhr.addEventListener('timeout', () => {
                    log('请求超时!', 'error');
                    captchaImage.alt = '请求超时';
                });
                
                // 设置超时时间
                xhr.timeout = 10000; // 10秒
                
                // 发送请求
                log('发送请求...', 'info');
                xhr.send();
            } catch (e) {
                log(`捕获到异常: ${e.message}`, 'error');
                log(`异常类型: ${e.constructor.name}`, 'error');
                log(`异常堆栈: ${e.stack}`, 'error');
                captchaImage.alt = '代码异常';
            }
        }
        
        // 事件监听器
        refreshBtn.addEventListener('click', testCaptchaApi);
        
        // 页面加载时立即测试验证码API
        window.addEventListener('load', function() {
            log('页面加载完成，开始测试验证码API', 'info');
            log('后端服务地址: http://localhost:8000/api/auth/captcha', 'info');
            testCaptchaApi();
        });
        
        // 定期检查后端服务可用性
        setInterval(() => {
            const pingUrl = `http://localhost:8000/api/auth/captcha?ping=true&t=${new Date().getTime()}`;
            log(`定期检查后端服务...`, 'info');
            
            fetch(pingUrl, {
                method: 'GET',
                mode: 'cors',
                credentials: 'include',
                headers: {
                    'Accept': '*/*',
                    'Cache-Control': 'no-cache'
                }
            })
            .then(response => {
                log(`后端服务状态: ${response.status === 200 ? '可用' : '不可用'}`, response.status === 200 ? 'success' : 'error');
            })
            .catch(error => {
                log(`后端服务检查失败: ${error.message}`, 'error');
            });
        }, 30000); // 每30秒检查一次
    </script>
</body>
</html>